Skip to content

[ResponseOps] Cases analytics index synchronization#222820

Merged
adcoelho merged 7 commits intoelastic:cases-analytics-indexfrom
adcoelho:cai-synchronization
Jun 13, 2025
Merged

[ResponseOps] Cases analytics index synchronization#222820
adcoelho merged 7 commits intoelastic:cases-analytics-indexfrom
adcoelho:cai-synchronization

Conversation

@adcoelho
Copy link
Copy Markdown
Contributor

@adcoelho adcoelho commented Jun 5, 2025

Closes #221232

Merging into a feature branch

Summary

This PR adds:

  • Synchronization task registration.
  • Synchronization task scheduling.
  • Testing

How to test

A few things are needed.

  1. Create a role that has index creation permission. Below is what works for me; it might be overkill.
Screenshot 2025-04-25 at 11 30 45
  1. Create a user with the role created in step 1. Let's call the user index_creator. The password should be changeme.
Screenshot 2025-04-25 at 11 31 27
  1. Start Kibana with this user as the Elasticsearch user - yarn start with the option --elasticsearch.username=index_creator.

  2. You can check the content of these indexes in the Dev Tools.

GET /.internal.cases/_search
GET /.internal.cases-comments/_search
GET /.internal.cases-attachments/_search
  1. Create Cases, Comments, and Attachments.
  2. After about 5 minutes, check again the content of the indexes using the instructions in step 7.
  3. Confirm the Cases, Comments, and Attachments created in step 8 can be seen in the analytics indexes.

@adcoelho adcoelho self-assigned this Jun 5, 2025
@adcoelho adcoelho added Team:ResponseOps Platform ResponseOps team (formerly the Cases and Alerting teams) t// Feature:Cases Cases feature labels Jun 5, 2025
@adcoelho adcoelho requested a review from ersin-erdal June 5, 2025 13:48
@adcoelho adcoelho marked this pull request as ready for review June 10, 2025 12:28
@adcoelho adcoelho requested a review from a team as a code owner June 10, 2025 12:28
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/response-ops (Team:ResponseOps)

@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/response-ops-cases (Feature:Cases)

@adcoelho adcoelho force-pushed the cai-synchronization branch from 707b861 to 050f701 Compare June 11, 2025 09:08
@adcoelho adcoelho force-pushed the cai-synchronization branch from 9946246 to c393168 Compare June 12, 2025 07:27
@adcoelho
Copy link
Copy Markdown
Contributor Author

The failing functional tests with [.internal.cases-attachments] Failed to create the index. Error message: security_exception are happening because the internal user does not yet have permissions for those indexes.

Copy link
Copy Markdown
Contributor

@ersin-erdal ersin-erdal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM
Just added a question about number of reindexing attempts.
And functional test would be good for this. We can just create a case in the test and expect it to be reindexed in the analytics index.

Copy link
Copy Markdown
Member

@cnasikas cnasikas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!! LGTM! I left some comments. Most of them are nits.

Comment thread x-pack/platform/plugins/shared/cases/server/cases_analytics/analytics_index.ts Outdated
Comment thread x-pack/platform/plugins/shared/cases/server/plugin.ts Outdated
});
});

describe('Error handling', () => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For tests with try/catch, we should put it at the beginning of the test expect.assertions(1), so the test will fail if the assertion in the catch is not called for some reason.

expect(isRetryableError(e)).toBe(null);
}

expect(logger.error).toBeCalledWith(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I think expecting certain error messages can lead to tests that are not resilient to refactoring. For example, every time we make a small change in the message, we should also update all tests. What about just checking expect(logger.error).toHaveBeenCalled();

@adcoelho adcoelho force-pushed the cai-synchronization branch from c393168 to d97eeeb Compare June 13, 2025 12:22
@adcoelho adcoelho merged commit 7b1e564 into elastic:cases-analytics-index Jun 13, 2025
8 of 10 checks passed
@elasticmachine
Copy link
Copy Markdown
Contributor

elasticmachine commented Jun 13, 2025

💔 Build Failed

Failed CI Steps

Test Failures

  • [job] [logs] FTR Configs #71 / alerting api integration security and spaces enabled - Group 2 Alerts alert deletion schedule alert deletion space_1_all at space1 should delete the correct of alerts - all category inactive alerts
  • [job] [logs] Jest Tests #14 / SynchronizationTaskRunner Error handling An error is thrown for invalid task state
  • [job] [logs] Jest Tests #14 / SynchronizationTaskRunner Error handling An error is thrown for invalid task state
  • [job] [logs] FTR Configs #118 / task_manager check_registered_task_types should check changes on all registered task types
  • [job] [logs] FTR Configs #118 / task_manager check_registered_task_types should check changes on all registered task types

Metrics [docs]

‼️ ERROR: no builds found for mergeBase sha [fa8ef65]

History

cc @adcoelho

adcoelho added a commit that referenced this pull request Jun 24, 2025
This PR is for a feature branch that is being merged into main.

The relevant PRs are:
- #219211
- #222820
- #223241
- #224388
- #224682

## Summary

This PR adds 4 new indexes with case analytics data, which are created
when the cases plugin starts.

  - `.internal.cases`
  - `.internal.cases-comments`
  - `.internal.cases-attachments`
  - `.internal.cases-activity`

After the indexes are created, a backfill task for each of them is
scheduled to run 1 minute after creation. This task populates the
indexes with relevant data from `.kibana_alerting_cases`.

A second type of task is registered, the index synchronization task.
Four of these tasks, one for each index, are scheduled to run every 5
minutes. The synchronization tasks populated the indexes with data from
`.kibana_alerting_cases` that was created or updated in the last five
minutes.

## How to test

You might want to start Kibana with `--verbose` to see relevant index
messages in the console.

Alternatively(what I normally do), is go to `analytics_index.ts`,
`backfill_task_runner.ts`, and `synchronization_task_runner.ts`, and
change the `logDebug` function to call `this.logger.info` instead. This
way, you will have less spam in the console.

Every log message starts with the index name between square brackets, so
you can look for `[.internal.cases-` and follow what is happening.

1. You should have some existing case data, so before anything else,
please create some activity, attachments, etc.
2. Add `xpack.cases.analytics.index.enabled: true` to `kibana.dev.yml`
and restart Kibana.
3. Check out [this
branch](elastic/elasticsearch#129414) from the
ES project.
4. Start Elastic Search with `yarn es source`. This will use the above
version of Elasticsearch.
5. Wait a bit for the indexes to be created and populated(backfilled).
6. Using the dev tools:
    - Confirm the indexes exist.
- Check the index mapping. Does it match the one in the code? Is the
`_meta` field correct?
-
`x-pack/platform/plugins/shared/cases/server/cases_analytics/******_index/mappings.ts`
    - Check that the painless scripts match the code.
-
`x-pack/platform/plugins/shared/cases/server/cases_analytics/******_index/painless_scripts.ts`
- Confirm your existing case data is in the indexes. (See **Queries**
section below.)
7. Play around with cases. Some examples:
    - Create a case
    - Change status/severity
    - Attach alerts
    - Add files
    - Change category/tags
    - Add comments
    - etc
8. Go to the dev tools again and confirm all this shows up in the
relevant indexes. (See **Queries** section below.)

## Queries

In addition to the ones, below I have a few more. Things like reindexing
with specific scripts or fetching relevant data from
`.kibana_alerting_cases`. Ping me if you want those queries.

### Checking index content
```
GET /.internal.cases/_search
GET /.internal.cases-comments/_search
GET /.internal.cases-attachments/_search
GET /.internal.cases-activity/_search
```

### Checking index mappings
```
GET /.internal.cases
GET /.internal.cases-comments
GET /.internal.cases-attachments
GET /.internal.cases-activity
```

### Fetching the painless scripts
```
GET /_scripts/cai_cases_script_1
GET /_scripts/cai_attachments_script_1
GET /_scripts/cai_comments_script_1
GET /_scripts/cai_activity_script_1
```

### Emptying the indexes

It is sometimes useful for testing.
```
POST /.internal.cases/_delete_by_query
POST /.internal.cases-comments/_delete_by_query
POST /.internal.cases-attachments/_delete_by_query
POST /.internal.cases-activity/_delete_by_query
```

### Deleting the indexes

It is sometimes useful for testing.
```
DELETE /.internal.cases
DELETE /.internal.cases-comments
DELETE /.internal.cases-attachments
DELETE /.internal.cases-activity
```

## Release notes

Four dedicated case analytics indexes were created, allowing users to
build dashboards and metrics over case data. These indexes are created
on Kibana startup and updated periodically with cases, comments,
attachments, and activity data.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: Christos Nasikas <christos.nasikas@elastic.co>
adcoelho added a commit to adcoelho/kibana that referenced this pull request Jun 24, 2025
This PR is for a feature branch that is being merged into main.

The relevant PRs are:
- elastic#219211
- elastic#222820
- elastic#223241
- elastic#224388
- elastic#224682

## Summary

This PR adds 4 new indexes with case analytics data, which are created
when the cases plugin starts.

  - `.internal.cases`
  - `.internal.cases-comments`
  - `.internal.cases-attachments`
  - `.internal.cases-activity`

After the indexes are created, a backfill task for each of them is
scheduled to run 1 minute after creation. This task populates the
indexes with relevant data from `.kibana_alerting_cases`.

A second type of task is registered, the index synchronization task.
Four of these tasks, one for each index, are scheduled to run every 5
minutes. The synchronization tasks populated the indexes with data from
`.kibana_alerting_cases` that was created or updated in the last five
minutes.

## How to test

You might want to start Kibana with `--verbose` to see relevant index
messages in the console.

Alternatively(what I normally do), is go to `analytics_index.ts`,
`backfill_task_runner.ts`, and `synchronization_task_runner.ts`, and
change the `logDebug` function to call `this.logger.info` instead. This
way, you will have less spam in the console.

Every log message starts with the index name between square brackets, so
you can look for `[.internal.cases-` and follow what is happening.

1. You should have some existing case data, so before anything else,
please create some activity, attachments, etc.
2. Add `xpack.cases.analytics.index.enabled: true` to `kibana.dev.yml`
and restart Kibana.
3. Check out [this
branch](elastic/elasticsearch#129414) from the
ES project.
4. Start Elastic Search with `yarn es source`. This will use the above
version of Elasticsearch.
5. Wait a bit for the indexes to be created and populated(backfilled).
6. Using the dev tools:
    - Confirm the indexes exist.
- Check the index mapping. Does it match the one in the code? Is the
`_meta` field correct?
-
`x-pack/platform/plugins/shared/cases/server/cases_analytics/******_index/mappings.ts`
    - Check that the painless scripts match the code.
-
`x-pack/platform/plugins/shared/cases/server/cases_analytics/******_index/painless_scripts.ts`
- Confirm your existing case data is in the indexes. (See **Queries**
section below.)
7. Play around with cases. Some examples:
    - Create a case
    - Change status/severity
    - Attach alerts
    - Add files
    - Change category/tags
    - Add comments
    - etc
8. Go to the dev tools again and confirm all this shows up in the
relevant indexes. (See **Queries** section below.)

## Queries

In addition to the ones, below I have a few more. Things like reindexing
with specific scripts or fetching relevant data from
`.kibana_alerting_cases`. Ping me if you want those queries.

### Checking index content
```
GET /.internal.cases/_search
GET /.internal.cases-comments/_search
GET /.internal.cases-attachments/_search
GET /.internal.cases-activity/_search
```

### Checking index mappings
```
GET /.internal.cases
GET /.internal.cases-comments
GET /.internal.cases-attachments
GET /.internal.cases-activity
```

### Fetching the painless scripts
```
GET /_scripts/cai_cases_script_1
GET /_scripts/cai_attachments_script_1
GET /_scripts/cai_comments_script_1
GET /_scripts/cai_activity_script_1
```

### Emptying the indexes

It is sometimes useful for testing.
```
POST /.internal.cases/_delete_by_query
POST /.internal.cases-comments/_delete_by_query
POST /.internal.cases-attachments/_delete_by_query
POST /.internal.cases-activity/_delete_by_query
```

### Deleting the indexes

It is sometimes useful for testing.
```
DELETE /.internal.cases
DELETE /.internal.cases-comments
DELETE /.internal.cases-attachments
DELETE /.internal.cases-activity
```

## Release notes

Four dedicated case analytics indexes were created, allowing users to
build dashboards and metrics over case data. These indexes are created
on Kibana startup and updated periodically with cases, comments,
attachments, and activity data.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: Christos Nasikas <christos.nasikas@elastic.co>
(cherry picked from commit e566fec)

# Conflicts:
#	x-pack/platform/plugins/shared/task_manager/server/mocks.ts
akowalska622 pushed a commit to akowalska622/kibana that referenced this pull request Jun 25, 2025
This PR is for a feature branch that is being merged into main.

The relevant PRs are:
- elastic#219211
- elastic#222820
- elastic#223241
- elastic#224388
- elastic#224682

## Summary

This PR adds 4 new indexes with case analytics data, which are created
when the cases plugin starts.

  - `.internal.cases`
  - `.internal.cases-comments`
  - `.internal.cases-attachments`
  - `.internal.cases-activity`

After the indexes are created, a backfill task for each of them is
scheduled to run 1 minute after creation. This task populates the
indexes with relevant data from `.kibana_alerting_cases`.

A second type of task is registered, the index synchronization task.
Four of these tasks, one for each index, are scheduled to run every 5
minutes. The synchronization tasks populated the indexes with data from
`.kibana_alerting_cases` that was created or updated in the last five
minutes.

## How to test

You might want to start Kibana with `--verbose` to see relevant index
messages in the console.

Alternatively(what I normally do), is go to `analytics_index.ts`,
`backfill_task_runner.ts`, and `synchronization_task_runner.ts`, and
change the `logDebug` function to call `this.logger.info` instead. This
way, you will have less spam in the console.

Every log message starts with the index name between square brackets, so
you can look for `[.internal.cases-` and follow what is happening.

1. You should have some existing case data, so before anything else,
please create some activity, attachments, etc.
2. Add `xpack.cases.analytics.index.enabled: true` to `kibana.dev.yml`
and restart Kibana.
3. Check out [this
branch](elastic/elasticsearch#129414) from the
ES project.
4. Start Elastic Search with `yarn es source`. This will use the above
version of Elasticsearch.
5. Wait a bit for the indexes to be created and populated(backfilled).
6. Using the dev tools:
    - Confirm the indexes exist.
- Check the index mapping. Does it match the one in the code? Is the
`_meta` field correct?
-
`x-pack/platform/plugins/shared/cases/server/cases_analytics/******_index/mappings.ts`
    - Check that the painless scripts match the code.
-
`x-pack/platform/plugins/shared/cases/server/cases_analytics/******_index/painless_scripts.ts`
- Confirm your existing case data is in the indexes. (See **Queries**
section below.)
7. Play around with cases. Some examples:
    - Create a case
    - Change status/severity
    - Attach alerts
    - Add files
    - Change category/tags
    - Add comments
    - etc
8. Go to the dev tools again and confirm all this shows up in the
relevant indexes. (See **Queries** section below.)

## Queries

In addition to the ones, below I have a few more. Things like reindexing
with specific scripts or fetching relevant data from
`.kibana_alerting_cases`. Ping me if you want those queries.

### Checking index content
```
GET /.internal.cases/_search
GET /.internal.cases-comments/_search
GET /.internal.cases-attachments/_search
GET /.internal.cases-activity/_search
```

### Checking index mappings
```
GET /.internal.cases
GET /.internal.cases-comments
GET /.internal.cases-attachments
GET /.internal.cases-activity
```

### Fetching the painless scripts
```
GET /_scripts/cai_cases_script_1
GET /_scripts/cai_attachments_script_1
GET /_scripts/cai_comments_script_1
GET /_scripts/cai_activity_script_1
```

### Emptying the indexes

It is sometimes useful for testing.
```
POST /.internal.cases/_delete_by_query
POST /.internal.cases-comments/_delete_by_query
POST /.internal.cases-attachments/_delete_by_query
POST /.internal.cases-activity/_delete_by_query
```

### Deleting the indexes

It is sometimes useful for testing.
```
DELETE /.internal.cases
DELETE /.internal.cases-comments
DELETE /.internal.cases-attachments
DELETE /.internal.cases-activity
```

## Release notes

Four dedicated case analytics indexes were created, allowing users to
build dashboards and metrics over case data. These indexes are created
on Kibana startup and updated periodically with cases, comments,
attachments, and activity data.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: Christos Nasikas <christos.nasikas@elastic.co>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature:Cases Cases feature Team:ResponseOps Platform ResponseOps team (formerly the Cases and Alerting teams) t//

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants